package com.winit.openapi.oauth.builder;

import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.annotation.Resource;

import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;

import com.alibaba.fastjson.JSONObject;
import com.winit.common.spi.command.GetByKeyCommand;
import com.winit.openapi.constants.ErrorCode;
import com.winit.openapi.exception.ApiException;
import com.winit.openapi.oauth.manager.APIDeveloperManager;
import com.winit.openapi.oauth.manager.UserAuthorizationManager;
import com.winit.openapi.oauth.util.OAuth2SecurityUtil;
import com.winit.openapi.oauth.vo.APIClientVo;
import com.winit.openapi.oauth.vo.APIDeveloperVo;
import com.winit.openapi.oauth.vo.UserAuthorizationVo;
import com.winit.openapi.util.APISysConfigUtil;
import com.winit.openapi.util.DateUtil;
import com.winit.ums.spi.UmsUserService;
import com.winit.ums.spi.vo.user.UserVO;

@Service("apiOAuhtBuilder")
public class APIOAuhtBuilder {

    @Resource
    private UserAuthorizationManager userAuthorizationManager;

    @Resource
    private APIDeveloperManager      apiDeveloperManager;
    @Resource
    private UmsUserService           umsUserService;

    @Resource
    private APISysConfigUtil         apiSysConfigUtil;

    public APIClientVo buildClientAdd(JSONObject json, APIDeveloperVo developer) {
        APIClientVo vo = new APIClientVo();
        if (json.containsKey("clientName")) {
            vo.setClientName(json.getString("clientName"));
        }
        if (json.containsKey("clientCode")) {
            vo.setClientCode(json.getString("clientCode"));
        }
        if (json.containsKey("type")) {
            vo.setClientType(json.getString("type"));
        }
        if (json.containsKey("redirectURL")) {
            vo.setRedirectUrl(json.getString("redirectURL"));
        }
        if (json.containsKey("isDefaultURL")) {
            vo.setIsDefaultUrl(json.getString("isDefaultURL"));
        }
        if (json.containsKey("logoImageUri")) {
            vo.setLogoImageUri(json.getString("logoImageUri"));
        }
        if (json.containsKey("comment")) {
            vo.setComment(json.getString("comment"));
        }
        // 默认审核通过
        vo.setStatus("Y");

        vo.setClientKey(OAuth2SecurityUtil.generateClientKey());
        vo.setClientSecret(OAuth2SecurityUtil.generateClientSecret());
        vo.setClientAuthUrl(generateClientAuthUrl(vo));

        vo.setDeveloperId(developer.getId());
        vo.setCreated(new Date());
        vo.setCreatedby(developer.getDeveloperAccount());
        vo.setUpdated(null);
        vo.setUpdatedby(null);
        vo.setIsActive("Y");
        vo.setIsDelete("N");

        return vo;

    }

    public void buildClientUpdate(JSONObject json, APIClientVo vo) {
        if (json.containsKey("type")) {
            // 修改应用的类型需要重新审核
            if (!vo.getClientType().equals(json.getString("type"))) {
                vo.setClientType(json.getString("type"));
                // vo.setStatus("N");
            }
        }
        if (json.containsKey("redirectURL")) {
            // 修改应用的URL需要重新审核
            if (!vo.getRedirectUrl().equals(json.getString("redirectURL"))) {
                vo.setRedirectUrl(json.getString("redirectURL"));
                // vo.setStatus("N");
            }
        }
        if (json.containsKey("isDefaultURL")) {
            vo.setIsDefaultUrl(json.getString("isDefaultURL"));
        }
        if (json.containsKey("clientCode")) {
            vo.setClientCode(json.getString("clientCode"));
        }
        if (json.containsKey("comment")) {
            vo.setComment(json.getString("comment"));
        }
        if (json.containsKey("logoImageUri")) {
            vo.setLogoImageUri(json.getString("logoImageUri"));
        }
        vo.setClientAuthUrl(generateClientAuthUrl(vo));
        vo.setUpdated(new Date());

        APIDeveloperVo developer = apiDeveloperManager.queryById(vo.getDeveloperId());
        vo.setUpdatedby(developer == null ? null : developer.getDeveloperAccount());

    }

    public List<Map<String, Object>> buildClientList(List<APIClientVo> clientList) {
        List<Map<String, Object>> List = new ArrayList<Map<String, Object>>();
        if (CollectionUtils.isEmpty(clientList)) {
            return List;
        }
        for (APIClientVo vo : clientList) {
            vo.setUserList(userAuthorizationManager.queryByClientId(vo.getId()));
            List.add(buildClientDetail(vo));
        }
        return List;

    }

    public Map<String, Object> buildClientDetail(APIClientVo client) {
        Map<String, Object> data = new HashMap<String, Object>();
        data.put("developerId", client.getDeveloperId());
        data.put("id", client.getId());
        data.put("clientId", client.getClientKey());
        data.put("clientName", client.getClientName());
        data.put("clientCode", client.getClientCode());
        data.put("type", client.getClientType());
        data.put("redirectURL", client.getRedirectUrl());
        data.put("isDefaultURL", client.getIsDefaultUrl());
        data.put("logoImageUri", client.getLogoImageUri());
        data.put("authUrl", client.getClientAuthUrl());
        data.put("status", client.getStatus());
        data.put("comment", client.getComment());

        data.put("userCount", client.getUserList() == null ? 0 : client.getUserList().size());
        // TODO 权限目前默认，未实现
        data.put("clientScope", "OSWH ISP");
        if ("Y".equals(client.getStatus())) {
            data.put("clientSecret", client.getClientSecret());
        }

        return data;
    }

    public Map<String, Object> buildClientInfoForSellerPortal(APIClientVo client, UserAuthorizationVo userAuthVo) {
        Map<String, Object> data = new HashMap<String, Object>();
        data.put("clientId", client.getClientKey());
        data.put("clientName", client.getClientName());
        data.put("clientCode", client.getClientCode());
        data.put("type", client.getClientType());
        data.put("logoImageUri", client.getLogoImageUri());
        data.put("status", client.getStatus());
        // 有效期
        Date dateStart = userAuthVo.getUpdated();
        if (dateStart == null) {
            dateStart = userAuthVo.getCreated();
        }
        data.put("isActive", userAuthVo.getIsActive());
        data.put("created", DateUtil.parse2String(dateStart, DateUtil.SIMPLE_DATE_STRING));
        data.put("expierTime", DateUtil.parse2String(userAuthVo.getExpireTime(), DateUtil.SIMPLE_DATE_STRING));
        data.put("accessToken", userAuthVo.getAccessToken());
        data.put("refreshToken", userAuthVo.getRefreshToken());

        return data;
    }

    public List<Map<String, Object>> buildUserAuthResult(List<UserAuthorizationVo> userAuriList, APIClientVo clientVo) {
        List<Map<String, Object>> userData = new ArrayList<Map<String, Object>>();
        if (CollectionUtils.isEmpty(userAuriList)) {
            return userData;
        }
        for (UserAuthorizationVo vo : userAuriList) {
            Map<String, Object> map = new HashMap<String, Object>();
            map.put("companyName", vo.getCompanyName());
            map.put("userName", vo.getUserName());
            map.put("bindingTime", DateUtil.parse2String(vo.getCreated(), DateUtil.SIMPLE_DATE_STRING));
            // TODO 权限目前默认，未实现
            map.put("scope", "OSWH ISP");
            map.put("expierTime", DateUtil.parse2String(vo.getExpireTime(), DateUtil.SIMPLE_DATE_STRING));
            map.put("status", vo.getIsActive());
            map.put("clientName", clientVo.getClientName());
            map.put("logoImageUri", clientVo.getLogoImageUri());
            userData.add(map);
        }
        return userData;
    }

    public Map<String, Object> buildSingleUserAuthResult(UserAuthorizationVo userAuthInfo, APIClientVo clientVo) {
        Map<String, Object> map = new HashMap<String, Object>();
        map.put("companyName", userAuthInfo.getCompanyName());
        map.put("userName", userAuthInfo.getUserName());
        map.put("bindingTime", DateUtil.parse2String(userAuthInfo.getCreated(), DateUtil.SIMPLE_DATE_STRING));
        // TODO 权限目前默认，未实现
        map.put("scope", "OSWH ISP");
        map.put("expierTime", DateUtil.parse2String(userAuthInfo.getExpireTime(), DateUtil.SIMPLE_DATE_STRING));
        map.put("status", userAuthInfo.getIsActive());
        map.put("clientName", clientVo.getClientName());
        map.put("logoImageUri", clientVo.getLogoImageUri());
        return map;
    }

    public APIDeveloperVo buildDeveloperAdd(JSONObject json) {
        APIDeveloperVo vo = new APIDeveloperVo();
        if (json.containsKey("platformName")) {
            vo.setPlatformName(json.getString("platformName"));
        }
        if ("winit".equals(json.getString("mode"))) {
            String winitUserName = json.getString("developerAccount");
            GetByKeyCommand<String> command = new GetByKeyCommand<String>();
            command.setSearchKey(winitUserName);
            UserVO userVo = umsUserService.queryByUsername(command);
            if (userVo == null) {
                throw new ApiException(ErrorCode.OAUTH_WINIT_USERNAME_NOT_EXISTS_ERROR);
            }
            vo.setWinitUserId(userVo.getId());
            vo.setDeveloperAccount(OAuth2SecurityUtil.generateDeveloperAccount(winitUserName));
            vo.setDeveloperPassword(OAuth2SecurityUtil.generateDeveloperAccountPassword(winitUserName));
            vo.setCreatedby(winitUserName);
        } else {
            if (json.containsKey("developerAccount")) {
                vo.setDeveloperAccount(json.getString("developerAccount"));
            }
            if (json.containsKey("password")) {
                String password = json.getString("password");
                vo.setDeveloperPassword(OAuth2SecurityUtil.md5AndSha256(password, OAuth2SecurityUtil.md5(password)));
            }
            vo.setCreatedby(vo.getDeveloperAccount());
        }
        if (json.containsKey("type")) {
            vo.setDeveloperType(json.getString("type"));
        }
        if (json.containsKey("contactPersonMobile")) {
            String phoneNo = json.getString("contactPersonMobile");
            APIDeveloperVo developer = new APIDeveloperVo();
            developer.setContactPersonMobile(phoneNo);
            developer.setIsActive("Y");
            developer.setIsDelete("N");
            if (apiDeveloperManager.find(developer) != null) {
                throw new ApiException(ErrorCode.OAUTH_DEVELOPER_PHONE_EXISTS_ERROR, phoneNo);
            }

            vo.setContactPersonMobile(json.getString("contactPersonMobile"));
        }
        if (json.containsKey("contactPersonName")) {
            vo.setContactPersonName(json.getString("contactPersonName"));
        }
        if (json.containsKey("email")) {
            vo.setEmail(json.getString("email"));
        }

        vo.setStatus("Y");

        vo.setCreated(new Date());
        vo.setUpdated(null);
        vo.setUpdatedby(null);
        vo.setIsActive("Y");
        vo.setIsDelete("N");

        return vo;
    }

    public APIDeveloperVo buildDeveloperUpdate(JSONObject json, APIDeveloperVo vo) {
        if (json.containsKey("platformName")) {
            vo.setPlatformName(json.getString("platformName"));
        }
        if (json.containsKey("developerAccount")) {
            vo.setDeveloperAccount(json.getString("developerAccount"));
        }
        if (json.containsKey("password")) {
            vo.setDeveloperPassword(json.getString("password"));
        }
        if (json.containsKey("type")) {
            vo.setDeveloperType(json.getString("type"));
        }
        if (json.containsKey("contactPersonMobile")) {
            vo.setContactPersonMobile(json.getString("contactPersonMobile"));
        }
        if (json.containsKey("contactPersonName")) {
            vo.setContactPersonName(json.getString("contactPersonName"));
        }
        if (json.containsKey("email")) {
            vo.setEmail(json.getString("email"));
        }

        vo.setStatus("Y");

        vo.setUpdated(new Date());
        vo.setUpdatedby(vo.getDeveloperAccount());
        vo.setIsActive("Y");
        vo.setIsDelete("N");

        return vo;
    }

    /**
     * 生成应用授权链接
     * 
     * @param vo
     */
    public String generateClientAuthUrl(APIClientVo vo) {
        String serverUrl = apiSysConfigUtil.getConfigValueByKey("API_OAUTH_SERVER_URL");
        if (StringUtils.isBlank(serverUrl)) {
            return "http://127.0.0.1:780/openapi/oauth2";
        }
        StringBuffer url = new StringBuffer(serverUrl.trim());
        url.append("/authorize?response_type=token");
        if (StringUtils.isNotBlank(vo.getClientKey())) {
            url.append("&client_id=");
            url.append(vo.getClientKey());
        }
        if (StringUtils.isNotBlank(vo.getRedirectUrl())) {
            url.append("&redirect_uri=");
            url.append(vo.getRedirectUrl());
        }
        url.append("&scope=");
        url.append("OSWH ISP");

        return url.toString();

    }

}
